package com.wust.modules.codegenerate.generate.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.wust.modules.codegenerate.util.CodeUtil;
import com.wust.modules.codegenerate.generate.prop.FileProperties;
import com.wust.modules.codegenerate.generate.impl.util.GenerateUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import com.wust.modules.codegenerate.database.DbReadTableUtil;
import com.wust.modules.codegenerate.generate.IGenerate;
import com.wust.modules.codegenerate.generate.pojo.ColumnVo;
import com.wust.modules.codegenerate.generate.pojo.onetomany.MainTableVo;
import com.wust.modules.codegenerate.generate.pojo.onetomany.SubTableVo;
import com.wust.modules.codegenerate.generate.util.NonceUtils;

/**
 * @author wanheng
 */
@Slf4j
@AllArgsConstructor
public class CodeGenerateOneToMany extends GenerateUtil implements IGenerate {

    public static String a = "A";
    public static String b = "B";
    private MainTableVo mainTableVo;
    private List<ColumnVo> columnVoList;
    private List<ColumnVo> columnVoList1;
    private List<SubTableVo> subTableVoList;

    @Override
    public Map<String, Object> getTableMap() throws Exception {
        HashMap hashMap = new HashMap();
        hashMap.put("bussiPackage", CodeUtil.bussiPackage);
        hashMap.put("entityPackage", this.mainTableVo.getEntityPackage());
        hashMap.put("entityName", this.mainTableVo.getEntityName());
        hashMap.put("tableName", this.mainTableVo.getTableName());
        hashMap.put("ftl_description", this.mainTableVo.getFtlDescription());
        hashMap.put("primaryKeyField", CodeUtil.dbTableId);
        if (this.mainTableVo.getFieldRequiredNum() == null) {
            this.mainTableVo.setFieldRequiredNum(StringUtils.isNotEmpty(CodeUtil.n) ? Integer.parseInt(CodeUtil.n) : -1);
        }

        if (this.mainTableVo.getSearchFieldNum() == null) {
            this.mainTableVo.setSearchFieldNum(StringUtils.isNotEmpty(CodeUtil.pageSearchFiledNum) ? Integer.parseInt(CodeUtil.pageSearchFiledNum) : -1);
        }

        if (this.mainTableVo.getFieldRowNum() == null) {
            this.mainTableVo.setFieldRowNum(Integer.parseInt(CodeUtil.q));
        }

        hashMap.put("tableVo", this.mainTableVo);

        try {
            if (this.columnVoList == null || this.columnVoList.size() == 0) {
                this.columnVoList = DbReadTableUtil.getColumns(this.mainTableVo.getTableName());
            }

            if (this.columnVoList1 == null || this.columnVoList1.size() == 0) {
                this.columnVoList1 = DbReadTableUtil.getColumnList(this.mainTableVo.getTableName());
            }

            hashMap.put("columns", this.columnVoList);
            hashMap.put("originalColumns", this.columnVoList1);
            Iterator iterator = this.columnVoList1.iterator();

            while(iterator.hasNext()) {
                ColumnVo columnVo = (ColumnVo) iterator.next();
                if (columnVo.getFieldName().toLowerCase().equals(CodeUtil.dbTableId.toLowerCase())) {
                    hashMap.put("primaryKeyPolicy", columnVo.getFieldType());
                }
            }

            iterator = this.subTableVoList.iterator();

            while(iterator.hasNext()) {
                SubTableVo subTableVo = (SubTableVo) iterator.next();
                List list;
                if (subTableVo.getColums() == null || subTableVo.getColums().size() == 0) {
                    list = DbReadTableUtil.getColumns(subTableVo.getTableName());
                    subTableVo.setColums(list);
                }

                if (subTableVo.getOriginalColumns() == null || subTableVo.getOriginalColumns().size() == 0) {
                    list = DbReadTableUtil.getColumnList(subTableVo.getTableName());
                    subTableVo.setOriginalColumns(list);
                }

                String[] foreignKeys = subTableVo.getForeignKeys();
                ArrayList arrayList = new ArrayList();
                String[] foreignKeys1 = foreignKeys;
                int length = foreignKeys.length;

                for(int i = 0; i < length; ++i) {
                    String foreignKey = foreignKeys1[i];
                    arrayList.add(DbReadTableUtil.getUpCamelCase(foreignKey));
                }

                subTableVo.setForeignKeys((String[]) arrayList.toArray(new String[0]));
                subTableVo.setOriginalForeignKeys(foreignKeys);
            }

            hashMap.put("subTables", this.subTableVoList);
        } catch (Exception e) {
            throw e;
        }

        long currentTimeMillis = NonceUtils.getSecureRandomLong() + NonceUtils.getCurrentTimeMillis();
        hashMap.put("serialVersionUID", String.valueOf(currentTimeMillis));
        log.info("code template data: " + hashMap.toString());
        return hashMap;
    }

    @Override
    public List<String> generateCodeFile(String stylePath) throws Exception {
        String filePath = CodeUtil.filePath;
        Map map = this.getTableMap();
        String templatePath = CodeUtil.templatePath;
        if ("code/code-template".equals(substring(templatePath, "/"))) {
            templatePath = "/" + substring(templatePath, "/") + "/onetomany";
            CodeUtil.setTemplatePath(templatePath);
        }

        FileProperties fileProperties = new FileProperties(templatePath);
        fileProperties.setStylePath(stylePath);
        this.generate(fileProperties, filePath, map);
        log.info("----- code ---- generate  code  success =======> 主表名：" + this.mainTableVo.getTableName());
        return this.arrayList;
    }

    @Override
    public List<String> generateCodeFile(String projectPath, String templatePath, String stylePath) throws Exception {
        if (projectPath != null && !"".equals(projectPath)) {
            CodeUtil.setFilePath(projectPath);
        }

        if (templatePath != null && !"".equals(templatePath)) {
            CodeUtil.setTemplatePath(templatePath);
        }

        this.generateCodeFile(stylePath);
        return this.arrayList;
    }
}
